package com.service.tm;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.common.DateUtils;
import com.common.StringUtils;
import com.common.easyui.EasyuiUtils;
import com.common.http.HttpResult;
import com.common.http.HttpStatus;
import com.common.model.Global;
import com.common.spring.SpringMvcUtils;
import com.common.utils.RSAUtils;
import com.dao.sale.ContractSignDao;
import com.dao.sys.MessageDao;
import com.dao.sys.SysDao;
import com.dao.sys.SysManageMapper;
import com.dao.sys.UserDao;
import com.dao.tm.PlanDao;
import com.dao.tm.StoreDao;
import com.dao.tm.TransferDao;
import com.enums.DictEnum;
import com.enums.FactoryEnum;
import com.enums.SaleOrderTypeEnum;
import com.enums.StoreEnum;
import com.enums.SysRoleEnum;
import com.enums.TmPlanStatusEnum;
import com.enums.TransportModeEnum;
import com.model.external.sap.SapPlanGoodModel;
import com.model.sale.ContractSignModel;
import com.model.sys.MessageModel;
import com.model.sys.SysDict;
import com.model.sys.SysUser;
import com.model.sys.UserModel;
import com.model.tm.PlanModel;
import com.model.tm.StoreModel;
import com.model.tm.TransferModel;
import com.service.external.oncard.EmsService;
import com.service.external.sap.CallSapRfcService;
import com.service.external.tm.TmService;
import com.service.purchase.CommonService;
import com.service.sys.SysDictService;
import com.service.sys.UserService;

@Service("tmPlanService")
public class PlanService {
	static final Logger logger = LoggerFactory.getLogger(PlanService.class);

	@Autowired
	PlanDao planDao;
	@Autowired
	CommonService commonService;
	@Autowired
	CallSapRfcService callSapRfcService;
	@Autowired
	MessageDao messageDao;
	@Autowired
	UserService userService;
	@Autowired
	SysDao sysDao;
	@Autowired
	SysDictService sysDictService;
	@Autowired
	ContractSignDao contractSignDao;
	@Autowired
	SysManageMapper sysManageMapper;
	@Autowired
	TmService tmService;
	@Autowired
	StoreDao storeDao;
	@Autowired
	TransferDao transferDao;
	@Autowired
	UserDao userDao;
	@Autowired
	EmsService emsService;

	@Value("${spring.active}")
	String activeProfile;
	@Value("${yunlian.url_trace}")
	String urlTrace;
	@Value("${yunlian.RSA-public}")
	String rsaPublic;
	@Value("${yunlian.appKey}")
	String appKey;

	public HttpResult selectContractList(Map<String, Object> queryMap) {
		HttpResult httpResult = new HttpResult();
		EasyuiUtils.addPageNum(queryMap);
		EasyuiUtils.addFilter(queryMap);
		List<ContractSignModel> list = new ArrayList<ContractSignModel>();
		httpResult.setRows(list);
		httpResult.setTotal(0);

		SysUser sysUser = SpringMvcUtils.getSysUser();
		List<HashMap<String, Object>> permiHashMaps = sysManageMapper.selectUrlAndPermissionMap(sysUser.getUserid());
		for (HashMap<String, Object> hashMap : permiHashMaps) {
			if (hashMap.containsKey("PERMISSIONS")
					&& hashMap.get("PERMISSIONS").toString().contains(SysRoleEnum.serviceBtn.getName())) {
				list = contractSignDao.selectList(queryMap);
				int count = contractSignDao.selectListCount(queryMap);
				httpResult.setRows(list);
				httpResult.setTotal(count);
			}
		}

		return httpResult;
	}

	/**
	 * 返回66云链轨迹接口
	 * 
	 * @param transportCode
	 * @return
	 */
	public HttpResult openTmUrl(String transportCode, String tmCarrierName) {
		HttpResult httpResult = new HttpResult();
		String url = "%s?appKey=%s&sign=%s";
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("consigNo", transportCode);
		jsonObject.put("consigName", tmCarrierName);
		jsonObject.put("time", DateUtils.getCurrentTime());
//		String dataString = "{\"consigNo\":\"SP-YSD202312040044\",\"consigName\":\"大连国通集装箱运输有限公司\",\"time\":\"2023-12-04 09:37:00\"}";
		String dataString = JSONObject.toJSONString(jsonObject);
		String sign = null;
		try {
			sign = RSAUtils.encryptByPublicKey(dataString, rsaPublic);
			sign = URLEncoder.encode(sign, "utf-8");
		} catch (Exception e) {
			logger.error(e.getMessage());
			return HttpResult.error(e.getMessage());
		}
		url = String.format(url, urlTrace, appKey, sign);
		httpResult.setData(url);
		return httpResult;
	}

	/**
	 * 列表查询
	 *
	 * @param queryMap
	 * @return
	 */
	public HttpResult selectList(Map<String, Object> queryMap) {
		HttpResult httpResult = new HttpResult();
		EasyuiUtils.addPageNum(queryMap);
		EasyuiUtils.addFilter(queryMap);
		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (!sysUser.getSuperadmin().equals(Global.YES + "")) {
			if (StringUtils.isNotNull(sysUser.getBtnPermission())) {
				if (sysUser.getBtnPermission().contains(FactoryEnum.xy.getValue())
						|| sysUser.getBtnPermission().contains(FactoryEnum.sp.getValue())
						|| sysUser.getBtnPermission().contains(FactoryEnum.hb.getValue())
						|| sysUser.getBtnPermission().contains(FactoryEnum.hk.getValue())) {
					queryMap.put("facCodes", sysUser.getBtnPermission().split(","));
				}
			} else {
			}
		}
		List<PlanModel> list = planDao.selectList(queryMap);
		int count = planDao.selectListCount(queryMap);

		BigDecimal getSkuNum = list.stream().map(PlanModel::getSkuNum).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal getProNum = list.stream().map(PlanModel::getProNum).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal getPak1Num = list.stream().map(PlanModel::getPak1Num).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal getPak2Num = list.stream().map(PlanModel::getPak2Num).reduce(BigDecimal.ZERO, BigDecimal::add);
		List<PlanModel> footerList = new ArrayList<PlanModel>();
		PlanModel footerModel = new PlanModel();
		footerModel.setPlanName("合计");
		footerModel.setSkuNum(getSkuNum);
		footerModel.setProNum(getProNum);
		footerModel.setPak1Num(getPak1Num);
		footerModel.setPak2Num(getPak2Num);
		footerList.add(footerModel);

		httpResult.setFooter(footerList);
		httpResult.setRows(list);
		httpResult.setTotal(count);
		logger.info("selectList:{}", list);
		return httpResult;
	}

	/**
	 * 详情
	 * 
	 * @param
	 * @return
	 */
	public HttpResult selectInfor(String planId) {
		HttpResult httpResult = new HttpResult();
		PlanModel planModel = planDao.load(planId);
		httpResult.setData(planModel);
		httpResult.setCode(HttpStatus.SUCCESS_CODE);
		return httpResult;
	}

	/**
	 * 保存
	 *
	 * @param
	 * @return
	 */
	@Transactional
	public HttpResult save(PlanModel planModel) {
		if (planModel == null) {
			return HttpResult.error("参数不能为空");
		}
		if (planModel.getSendDate().compareTo(DateUtils.getCurrentDate()) < 0) {
			return HttpResult.error("预计发货时间只能选择今日之后！");
		}
		if (planModel.getSendDate().compareTo(DateUtils.addDays(DateUtils.getCurrentDate(), 2)) > 0) {
//			return HttpResult.error("预计发货时间只能选择三天之内！");
		}

		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (StringUtils.isNotNull(planModel.getPlanId())) {
			if (!sysUser.getSuperadmin().equals(Global.YES + "")
					&& !planModel.getCreateId().equals(sysUser.getUserid())) {
				return HttpResult.error("非本人创建计划，不能编辑");
			}
		}
		// 保存
		HttpResult httpResult = new HttpResult();
		int result = 0;
		// 获取oa部门
		UserModel userModel = userDao.load(planModel.getDraCreatorId());
		if (userModel != null) {
			planModel.setDeptName(userModel.getOaDeptName());
		}
		planModel.setTransportCode(Global.NO + "");
		planModel.setGodNum(Global.NO + "");
		planModel.setEmsBillNum(Global.NO + "");
		if (!StringUtils.isNotNull(planModel.getPlanId())) {
			planModel.setPlanId(UUID.randomUUID().toString());
			planModel.setPlanCode(commonService.createCode("tm_plan", "plan_code"));
			result = planDao.insert(planModel);
		} else {
			result = planDao.update(planModel);
		}
		if (result > 0) {
			httpResult.setMsg(planModel.getStatus().equals(Global.YES + "") ? "提交成功!" : "保存成功!");
			httpResult.setData(planModel);
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg(planModel.getStatus().equals(Global.YES + "") ? "提交失败!" : "保存失败!");
		}
		return httpResult;
	}

	// 获取产品发货日库存
	private BigDecimal getSumStore(PlanModel planModel) {
		BigDecimal sumDecimal = new BigDecimal(0);
		HashMap<String, Object> planMap = new HashMap<String, Object>();
		planMap.put("planSum", Global.YES + "");
		planMap.put("proCode", planModel.getProCode());
		planMap.put("facCode", planModel.getFacCode());
		planMap.put("stoCode", planModel.getStoCode());
		planMap.put("sendDate", planModel.getSendDate());
		List<PlanModel> planModels = planDao.selectList(planMap);
		sumDecimal = planModels.stream().map(PlanModel::getPlanPreNum).reduce(BigDecimal.ZERO, BigDecimal::add);
		return sumDecimal;
	}

	// 判断库存
	private HttpResult checkSto(PlanModel planModel) {
		StoreModel storeModel = storeDao.load(planModel.getFacCode(), planModel.getStoCode(), planModel.getProCode());
		if (storeModel != null) {
			// 获取预装数量
			BigDecimal yzBigDecimal = new BigDecimal(0);
			if (StringUtils.isNotNull(planModel.getPlanPreCode())) {
				for (String planString : planModel.getPlanPreCode().split(",")) {
					PlanModel yzModel = planDao.selectByPlanCode(planString);
					if (yzModel != null) {
						yzBigDecimal = yzBigDecimal.add(yzModel.getPlanPreNum());
					}
				}
			}
			// 获取主产品数量
			TransferModel transferModel = transferDao.load(planModel.getProCode(), planModel.getFacCode());
			StoreModel mainStoreModel = new StoreModel();
			if (transferModel != null) {
				mainStoreModel = storeDao.load(planModel.getFacCode(), planModel.getStoCode(),
						transferModel.getMainCode());
				if (mainStoreModel == null) {
					mainStoreModel = new StoreModel();
				}
			}
			if (mainStoreModel != null) {
				mainStoreModel.setStoTodayResidue(mainStoreModel.getStoTodayResidue() == null ? BigDecimal.ZERO
						: mainStoreModel.getStoTodayResidue());
				mainStoreModel.setStoTomorowResidue(mainStoreModel.getStoTomorowResidue() == null ? BigDecimal.ZERO
						: mainStoreModel.getStoTomorowResidue());
				mainStoreModel.setStoAcquiredResidue(mainStoreModel.getStoAcquiredResidue() == null ? BigDecimal.ZERO
						: mainStoreModel.getStoAcquiredResidue());
			}
			// 当主产品时，获取被转换数量
			HashMap<String, Object> transferMap = new HashMap<>();
			transferMap.put("mainCode", planModel.getProCode());
			transferMap.put("facCode", planModel.getFacCode());
			List<TransferModel> transferModels = transferDao.selectList(transferMap);
			BigDecimal tranferBigDecimal = new BigDecimal(0);
			for (TransferModel mainTransferModel : transferModels) {
				StoreModel tranferStoreModel = storeDao.load(planModel.getFacCode(), planModel.getStoCode(),
						mainTransferModel.getProCode());
				if (tranferStoreModel != null) {
					if (planModel.getSendDate().equals(DateUtils.getCurrentDate())) {
						tranferBigDecimal = tranferBigDecimal.add(tranferStoreModel.getStoTodayPlan());
					} else if (planModel.getSendDate().equals(DateUtils.addDays(DateUtils.getCurrentDate(), 1))) {
						tranferBigDecimal = tranferBigDecimal.add(tranferStoreModel.getStoTomorowPlan());
					} else if (planModel.getSendDate().equals(DateUtils.addDays(DateUtils.getCurrentDate(), 2))) {
						tranferBigDecimal = tranferBigDecimal.add(tranferStoreModel.getStoAcquiredPlan());
					}
				}
			}

			BigDecimal sumDecimal = getSumStore(planModel);
			if (planModel.getSendDate().equals(DateUtils.getCurrentDate())) {
				BigDecimal residuDecimal = storeModel.getStoTodayStore().subtract(storeModel.getStoOccupy())
						.subtract(sumDecimal).subtract(planModel.getProNum()).add(yzBigDecimal)
						.add(mainStoreModel.getStoTodayResidue()).subtract(tranferBigDecimal);// 本日库存-交货占用-排货计划占用+预装+主产品剩余
				if (residuDecimal.compareTo(BigDecimal.ZERO) < 0) {
					String msgString = String.format(
							"(%s):本日库存(%s)-交货占用(%s)-本日排货占用(%s)-本次占用(%s)+预装释放(%s)+主产品(%s)-被转换(%s)小于0，无法创建！",
							planModel.getPlanName(), storeModel.getStoTodayStore(), storeModel.getStoOccupy(),
							sumDecimal, planModel.getProNum(), yzBigDecimal, mainStoreModel.getStoTodayResidue(),
							tranferBigDecimal);
					return HttpResult.error(msgString);
				}
			} else if (planModel.getSendDate().equals(DateUtils.addDays(DateUtils.getCurrentDate(), 1))) {
				BigDecimal residuDecimal = storeModel.getStoTomorowStore().subtract(sumDecimal)
						.subtract(planModel.getProNum()).add(yzBigDecimal).add(mainStoreModel.getStoTomorowResidue())
						.subtract(tranferBigDecimal);// 库存-交货占用-排货计划占用
				if (residuDecimal.compareTo(BigDecimal.ZERO) < 0) {
					String msgString = String.format(
							"(%s):次日库存(%s)-明日排货占用(%s)-本次占用(%s)+预装释放(%s)+主产品(%s)-被转换(%s)小于0，无法创建！",
							planModel.getPlanName(), storeModel.getStoTomorowStore(), sumDecimal, planModel.getProNum(),
							yzBigDecimal, mainStoreModel.getStoTomorowResidue(), tranferBigDecimal);
					return HttpResult.error(msgString);
				}
			} else if (planModel.getSendDate().equals(DateUtils.addDays(DateUtils.getCurrentDate(), 2))) {
				BigDecimal residuDecimal = storeModel.getStoAcquiredStore().subtract(sumDecimal)
						.subtract(planModel.getProNum()).add(yzBigDecimal).add(mainStoreModel.getStoAcquiredResidue())
						.subtract(tranferBigDecimal);// 库存-交货占用-排货计划占用
				if (residuDecimal.compareTo(BigDecimal.ZERO) < 0) {
					String msgString = String.format(
							"(%s):后日库存(%s)-后日排货占用(%s)-本次占用(%s)+预装释放(%s)+主产品(%s)-被转换(%s)小于0，无法创建！",
							planModel.getPlanName(), storeModel.getStoAcquiredStore(), sumDecimal,
							planModel.getProNum(), yzBigDecimal, mainStoreModel.getStoAcquiredResidue(),
							tranferBigDecimal);
					return HttpResult.error(msgString);
				}
			}

		} else {
			if (!activeProfile.equals("dev")) {
				return HttpResult.error("查询不到该产品库存信息,请在库存展示页面点击‘刷新’按钮！");
			}
		}
		return HttpResult.ok();
	}

	/**
	 * 提交
	 *
	 * @param
	 * @return
	 */
	public HttpResult commit(PlanModel planModel) {
		if (planModel == null) {
			return HttpResult.error("参数不能为空");
		}
//		HttpResult stoHttpResult = checkSto(planModel);
//		if (stoHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
//			return HttpResult.error(stoHttpResult.getMsg());
//		}
		HttpResult httpResult = new HttpResult();
		int result = 0;

		SysUser sysUser = SpringMvcUtils.getSysUser();
		// 提交
		planModel.setPlanServiceAccount(sysUser.getLoginname());
		planModel.setPlanServiceStatus(Global.YES + "");
		planModel.setPlanServiceName(sysUser.getUsername());
		planModel.setPlanServiceTime(DateUtils.getCurrentTime());
		planModel.setPlanPreNum(planModel.getProNum());
//		result = planDao.update(planModel);
		// 审核
		JSONObject jsonObject = new JSONObject();
		List<PlanModel> planModels = new ArrayList<PlanModel>();
		planModels.add(planModel);
		jsonObject.put("rows", planModels);
		jsonObject.put("checkDept", "客服");
		jsonObject.put("status", Global.YES);
		jsonObject.put("remark", "");
		HttpResult checkHttpResult = check(jsonObject);
		if (checkHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
			return checkHttpResult;
		}
		result++;
		if (result > 0) {
			httpResult.setMsg(planModel.getPlanServiceStatus().equals(Global.YES + "") ? "提交成功!" : "保存成功!");
			httpResult.setData(planModel);
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg(planModel.getPlanServiceStatus().equals(Global.YES + "") ? "提交失败!" : "保存失败!");
		}
		return httpResult;
	}

	public void insertMsg(PlanModel planModel, String userEnum, String pre) {
		List<HashMap<String, Object>> serviceHashMaps = sysDao.queryItemByRoleName(userEnum);
		for (HashMap<String, Object> serviceHashMap : serviceHashMaps) {
			MessageModel messageModel = new MessageModel();
			messageModel.setMsgId(UUID.randomUUID().toString());
			messageModel.setMsgReceiveId(serviceHashMap.get("wx").toString());
			messageModel.setMsgReceiveName(serviceHashMap.get("username").toString());
			messageModel.setMsgContent(DateUtils.getCurrentTime() + pre + planModel.getPlanName());
			messageModel.setMsgType(com.enums.MsgEnum.qywx.getValue());
			messageDao.insert(messageModel);
		}
	}

	/**
	 * 审核
	 * 
	 * @param hashMap
	 * @return
	 */
	public HttpResult check(JSONObject hashMap) {
		if (hashMap.get("rows") == null) {
			return HttpResult.error("无数据");
		}
		int result = 0;
		JSONArray jsonArray = hashMap.getJSONArray("rows");
		List<PlanModel> planModels = JSONObject.parseArray(jsonArray.toJSONString(), PlanModel.class);
		for (PlanModel planModel : planModels) {
//			if (hashMap.get("status").toString().equals(Global.NO + "")) {
//				continue;
//			}
			planModel = planDao.load(planModel.getPlanId());
			if (!planModel.getStatus().equals(Global.NO + "")
					&& !planModel.getStatus().equals(TmPlanStatusEnum.two.getValue())
					&& !planModel.getStatus().equals(TmPlanStatusEnum.one.getValue())) {
				continue;
			}
			SysUser sysUser = SpringMvcUtils.getSysUser();
			String deptString = hashMap.get("checkDept").toString();
			switch (deptString) {
			case "客服":
				// 库存校验
				HttpResult stoHttpResult = checkSto(planModel);
				if (stoHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
					return HttpResult.error(stoHttpResult.getMsg());
				}
				// 更新预装状态为已完成
				if (StringUtils.isNotNull(planModel.getPlanPreCode())) {
					for (String planString : planModel.getPlanPreCode().split(",")) {
						PlanModel yzModel = planDao.selectByPlanCode(planString);
						if (yzModel != null) {
							yzModel.setPlanPreNum(yzModel.getPlanPreNum().subtract(planModel.getProNum()));
							if (yzModel.getPlanPreNum().compareTo(BigDecimal.ZERO) <= 0) {
								yzModel.setStatus(TmPlanStatusEnum.six.getValue());
								yzModel.setPlanPreNum(BigDecimal.ZERO);
							}
							planDao.update(yzModel);
						}
					}
				} else {
//					planModel.setPlanPreCode(Global.NO + "");
				}
				planModel.setPlanServiceAccount(sysUser.getLoginname());
				planModel.setPlanServiceName(sysUser.getUsername());
				planModel.setPlanServiceStatus(hashMap.get("status").toString());
				planModel.setPlanServiceRemark(hashMap.get("remark").toString());
				planModel.setPlanServiceTime(DateUtils.getCurrentTime());
				planModel.setPlanPreNum(planModel.getProNum());
				break;
			case "物流":
				planModel.setPlanTmAccount(sysUser.getLoginname());
				planModel.setPlanTmName(sysUser.getUsername());
				planModel.setPlanTmStatus(hashMap.get("status").toString());
				planModel.setPlanTmRemark(hashMap.get("remark").toString());
				planModel.setPlanTmTime(DateUtils.getCurrentTime());
				break;
			case "储运":
				planModel.setPlanStorAccount(sysUser.getLoginname());
				planModel.setPlanStorName(sysUser.getUsername());
				planModel.setPlanStorStatus(hashMap.get("status").toString());
				planModel.setPlanStorRemark(hashMap.get("remark").toString());
				planModel.setPlanStorTime(DateUtils.getCurrentTime());
				break;
			case "生产":
				planModel.setPlanProdAccount(sysUser.getLoginname());
				planModel.setPlanProdName(sysUser.getUsername());
				planModel.setPlanProdStatus(hashMap.get("status").toString());
				planModel.setPlanProdRemark(hashMap.get("remark").toString());
				planModel.setPlanProdTime(DateUtils.getCurrentTime());
				break;
			default:
				break;
			}
			HttpResult cheHttpResult = checkOne(planModel, hashMap);
			if (cheHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
				return cheHttpResult;
			} else {
				result++;
			}
		}
		HttpResult httpResult = new HttpResult();
		if (result > 0) {
			httpResult.setMsg("保存成功!");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("保存失败!");
		}
		return httpResult;
	}

	@Transactional
	private HttpResult checkOne(PlanModel planModel, JSONObject hashMap) {
		List<PlanModel> successList = new ArrayList<PlanModel>();
		int result = 0;
		// 自提时物流自动通过
		if (planModel.getDraTransportId().equals(TransportModeEnum.zt.getValue())
				|| planModel.getDraTransportId().equals(TransportModeEnum.ztbz.getValue())) {
			planModel.setPlanTmStatus(Global.YES + "");
			planModel.setTransportCode(Global.YES + "");
		}
		// 预装时物流自动通过
		if (planModel.getOrdCode().equals(SaleOrderTypeEnum.yz.getValue())) {
			planModel.setPlanTmStatus(Global.YES + "");
			planModel.setTransportCode(Global.YES + "");
			planModel.setEmsBillNum(Global.YES + "");
		}
		// 非成品库时，无需生产储运审核
		if (!planModel.getStoName().equals(StoreEnum.sto3001.getName())) {
			planModel.setPlanProdStatus(Global.YES + "");
			planModel.setPlanStorStatus(Global.YES + "");
			planModel.setEmsBillNum(Global.YES + "");
		}
		// 全部通过时，有效，否则未生效
		if (planModel.getPlanProdStatus() != null && planModel.getPlanTmStatus() != null
				&& planModel.getPlanStorStatus() != null && planModel.getPlanServiceStatus() != null
				&& planModel.getPlanProdStatus().equals(Global.YES + "")
				&& planModel.getPlanTmStatus().equals(Global.YES + "")
				&& planModel.getPlanStorStatus().equals(Global.YES + "")
				&& planModel.getPlanServiceStatus().equals(Global.YES + "")) {
			planModel.setStatus(Global.YES + "");
			// 预装不推送sap
			if (!planModel.getOrdCode().equals(SaleOrderTypeEnum.yz.getValue())
					&& !planModel.getOrdCode().equals(SaleOrderTypeEnum.jj.getValue())) {
				successList.add(planModel);
			}
		} else {
			planModel.setStatus(TmPlanStatusEnum.zero.getValue());
		}
		result += planDao.update(planModel);

		// 有一个不通过时，无效
		if (hashMap.get("status").toString().equals(Global.NO + "")) {
			planModel.setStatus(TmPlanStatusEnum.two.getValue());
			insertMsg(planModel, SysRoleEnum.planService.getName(), " 一条排货计划审核不通过：");
			insertMsg(planModel, SysRoleEnum.planTm.getName(), " 一条排货计划审核不通过：");
			insertMsg(planModel, SysRoleEnum.planStore.getName(), " 一条排货计划审核不通过：");
			insertMsg(planModel, SysRoleEnum.planProd.getName(), " 一条排货计划审核不通过：");
		}
		// 消息日志
		HashMap<String, Object> dicHashMap = new HashMap<String, Object>();
		dicHashMap.put("dicName", DictEnum.exceptTime);
		List<SysDict> sysDicts = sysDictService.selectDictListByParams(dicHashMap);
		String exceptTime = "";
		if (sysDicts != null && sysDicts.size() > 0) {
			exceptTime += sysDicts.get(0).getDicValue();
		}
		if ((planModel.getSendDate() + exceptTime)
				.compareTo(DateUtils.addDays(DateUtils.getCurrentDate(), 1) + DateUtils.getTime()) <= 0) {
			if (planModel.getOrdCode().compareTo(SaleOrderTypeEnum.jj.getValue()) <= 0) {
//				return HttpResult.error("当提交时间+24h大于预计发货日期时，订单类型必须为加急");
			}
			insertMsg(planModel, SysRoleEnum.planService.getName(), " 新增一条排货计划：");
			insertMsg(planModel, SysRoleEnum.planTm.getName(), " 新增一条排货计划：");
			insertMsg(planModel, SysRoleEnum.planStore.getName(), " 新增一条排货计划：");
			insertMsg(planModel, SysRoleEnum.planProd.getName(), " 新增一条排货计划：");
		}
		// 推送sap
		if (successList.size() > 0) {
			HttpResult rfcHttpResult = callSapRfcService.createPlan(successList);
			if (rfcHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
				// 强制手动事务回滚
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return rfcHttpResult;
			}
		}
		if (planModel.getStatus().equals(TmPlanStatusEnum.two.getValue())) {
			List<PlanModel> delModels = new ArrayList<PlanModel>();
			delModels.add(planModel);
			HttpResult rfcHttpResult = callSapRfcService.delPlan(delModels);
			if (rfcHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
				// 强制手动事务回滚
//				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//				return rfcHttpResult;
			}
		}
		return HttpResult.ok();
	}

	/**
	 * 删除
	 *
	 * @param
	 * @return
	 */
	@Transactional
	public HttpResult delete(String planId) {
		if (!StringUtils.isNotNull(planId)) {
			return HttpResult.error("参数不能为空");
		}
		PlanModel model = planDao.load(planId);
		if (model == null) {
			return HttpResult.error("无数据！");
		}
		if (!model.getStatus().equals(Global.NO + "")) {
			return HttpResult.error("非待提交状态，不可删除！");
		}

		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (StringUtils.isNotNull(model.getPlanId())) {
			if (!sysUser.getSuperadmin().equals(Global.YES + "") && !model.getCreateId().equals(sysUser.getUserid())) {
				return HttpResult.error("非本人创建计划，不能删除");
			}
		}
		HttpResult httpResult = new HttpResult();
		int result = planDao.delete(planId);

		if (result > 0) {
			httpResult.setMsg("删除成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	/**
	 * 撤回
	 *
	 * @param
	 * @return
	 */
	@Transactional
	public HttpResult back(String planId) {
		if (!StringUtils.isNotNull(planId)) {
			return HttpResult.error("参数不能为空");
		}
		PlanModel model = planDao.load(planId);

		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (StringUtils.isNotNull(model.getPlanId())) {
			if (!sysUser.getSuperadmin().equals(Global.YES + "") && !model.getCreateId().equals(sysUser.getUserid())) {
				return HttpResult.error("非本人创建计划，不能撤回");
			}
		}
		HttpResult httpResult = new HttpResult();
		model.setPlanServiceStatus("");
		int result = planDao.update(model);
		if (result > 0) {
			httpResult.setMsg("撤回成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	/**
	 * 获取交货单
	 * 
	 * @param planId
	 * @return
	 */
	public HttpResult getGodNum(String planId) {
		if (!StringUtils.isNotNull(planId)) {
			return HttpResult.error("参数不能为空");
		}
		PlanModel model = planDao.load(planId);

		List<PlanModel> planModels = new ArrayList<PlanModel>();
		planModels.add(model);
		HttpResult goodHttpResult = callSapRfcService.getPlan(planModels);
		List<SapPlanGoodModel> receiveList = JSONObject.parseArray(goodHttpResult.getData().toString(),
				SapPlanGoodModel.class);
		for (SapPlanGoodModel sapPlanGoodModel : receiveList) {
			if (StringUtils.isNullOrEmpty(sapPlanGoodModel.getGOD_CODE())) {
				return HttpResult.error("交货单号未创建");
			}
			model.setGodNum(sapPlanGoodModel.getGOD_CODE());
			model.setPlanSendRemark(sapPlanGoodModel.getGOD_REMARK());
			switch (sapPlanGoodModel.getSTATUS()) {
			case "C":
				model.setStatus(TmPlanStatusEnum.six.getValue());
				break;
			default:
				model.setStatus(TmPlanStatusEnum.five.getValue());
				break;
			}
		}

		HttpResult httpResult = new HttpResult();
		int result = planDao.update(model);
		if (result > 0) {
			httpResult.setMsg("查询成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	/**
	 * 获取运单
	 * 
	 * @param planId
	 * @return
	 */
	public HttpResult getTransportCode(String planId) {
		if (!StringUtils.isNotNull(planId)) {
			return HttpResult.error("参数不能为空");
		}
		PlanModel model = planDao.load(planId);

		HttpResult tmHttpResult = tmService.getYDH("'" + model.getGodNum() + "'");
		List<Object[]> arrayListResult = (List<Object[]>) tmHttpResult.getData();
		if (arrayListResult != null && arrayListResult.size() > 0) {
			Object[] objects = arrayListResult.get(0);
			model.setTransportCode(objects[0].toString());
			model.setTmDriver(objects[2].toString());
			model.setTmCar(objects[3].toString());
			model.setTmTank(objects[4].toString());
			model.setTmCarrierName(objects[5].toString());
		} else {
			return HttpResult.error("tm查询不到该交货单");
		}
		HttpResult httpResult = new HttpResult();
		int result = planDao.update(model);
		if (result > 0) {
			httpResult.setMsg("查询成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	/**
	 * 获取过磅单
	 * 
	 * @param planId
	 * @return
	 */
	public HttpResult getEms(String planId) {
		if (!StringUtils.isNotNull(planId)) {
			return HttpResult.error("参数不能为空");
		}
		PlanModel model = planDao.load(planId);
		if (model == null) {
			return HttpResult.error("不存在词条数据");
		}
		HttpResult tmHttpResult = emsService.getWeight("'" + model.getGodNum() + "'", model.getFacCode());
		List<Object[]> arrayListResult = (List<Object[]>) tmHttpResult.getData();
		if (arrayListResult != null && arrayListResult.size() > 0) {
			Object[] objects = arrayListResult.get(0);
			model.setEmsBillNum(objects[0].toString());
			model.setEmsInTime(objects[1] != null ? objects[1].toString() : null);
			model.setEmsOutTime(objects[2] != null ? objects[2].toString() : null);
			model.setEmsGross(objects[3] != null ? new BigDecimal(objects[3].toString()) : null);
			model.setEmsTare(objects[4] != null ? new BigDecimal(objects[4].toString()) : null);
			model.setEmsNnum(objects[5] != null ? new BigDecimal(objects[5].toString()) : null);
		} else {
			return HttpResult.error("一卡通查询不到该交货单");
		}
		HttpResult httpResult = new HttpResult();
		int result = planDao.update(model);
		if (result > 0) {
			httpResult.setMsg("查询成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	/**
	 * 取消
	 *
	 * @param
	 * @return
	 */
	@Transactional
	public HttpResult cansel(String planId, String planExcRemark) {
		if (!StringUtils.isNotNull(planId)) {
			return HttpResult.error("参数不能为空");
		}
		PlanModel model = planDao.load(planId);
		if (!model.getStatus().equals(TmPlanStatusEnum.one.getValue())
				&& !model.getStatus().equals(TmPlanStatusEnum.five.getValue())) {
			return HttpResult.error("只可取消已生效、执行中计划");
		}

		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (StringUtils.isNotNull(model.getPlanId())) {
			if (!sysUser.getSuperadmin().equals(Global.YES + "") && !model.getCreateId().equals(sysUser.getUserid())) {
				return HttpResult.error("非本人创建计划，不能取消");
			}
		}
		HttpResult httpResult = new HttpResult();

		model.setStatus(TmPlanStatusEnum.three.getValue());
		model.setPlanExcAccount(sysUser.getLoginname());
		model.setPlanExcName(sysUser.getUsername());
		model.setPlanExcStatus(TmPlanStatusEnum.three.getValue());
		model.setPlanExcRemark(planExcRemark);
		model.setReferPlanId(planId);
		model.setPlanPreNum(BigDecimal.ZERO);
		model.setPlanExcTime(DateUtils.getCurrentTime());

		insertMsg(model, SysRoleEnum.planService.getName(), "取消一条排货计划:");
		insertMsg(model, SysRoleEnum.planTm.getName(), "取消一条排货计划:");
		insertMsg(model, SysRoleEnum.planStore.getName(), "取消一条排货计划:");
		insertMsg(model, SysRoleEnum.planProd.getName(), "取消一条排货计划:");

		int result = planDao.update(model);

		// 删除sap排货计划
		if (StringUtils.isNotNull(model.getGodNum())) {
			List<PlanModel> successList = new ArrayList<PlanModel>();
			successList.add(model);
			HttpResult rfcHttpResult = callSapRfcService.delPlan(successList);
			if (rfcHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
				// 强制手动事务回滚
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return rfcHttpResult;
			}
		}

		if (result > 0) {
			httpResult.setMsg("取消成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	/**
	 * 转卸
	 *
	 * @param
	 * @return
	 */
	@Transactional
	public HttpResult transfercopy(String planId, String planExcRemark) {
		if (!StringUtils.isNotNull(planId)) {
			return HttpResult.error("参数不能为空");
		}
		PlanModel model = planDao.load(planId);
		if (!model.getStatus().equals(TmPlanStatusEnum.one.getValue())
				&& !model.getStatus().equals(TmPlanStatusEnum.six.getValue())) {
			return HttpResult.error("只可取消已生效、已完成排货计划");
		}
		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (StringUtils.isNotNull(model.getPlanId())) {
			if (!sysUser.getSuperadmin().equals(Global.YES + "") && !model.getCreateId().equals(sysUser.getUserid())) {
				return HttpResult.error("非本人创建计划，不能转卸");
			}
		}
		HttpResult httpResult = new HttpResult();

		model.setStatus(TmPlanStatusEnum.four.getValue());
		model.setPlanExcAccount(sysUser.getLoginname());
		model.setPlanExcName(sysUser.getUsername());
		model.setPlanExcStatus(TmPlanStatusEnum.three.getValue());
		model.setPlanExcTime(DateUtils.getCurrentTime());
		model.setPlanExcRemark(planExcRemark);
		model.setPlanPreNum(BigDecimal.ZERO);
		int result = planDao.update(model);
		// 删除sap排货计划
		if (StringUtils.isNotNull(model.getGodNum())) {
			List<PlanModel> successList = new ArrayList<PlanModel>();
			successList.add(model);
			HttpResult rfcHttpResult = callSapRfcService.delPlan(successList);
			if (rfcHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
				// 强制手动事务回滚
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return rfcHttpResult;
			}
		}

		PlanModel tranferModel = new PlanModel();
		BeanUtils.copyProperties(model, tranferModel);
		tranferModel.setPlanCode(commonService.createCode("tm_plan", "plan_code"));
		tranferModel.setPlanName(model.getPlanName() + "-转卸");
		tranferModel.setStatus(TmPlanStatusEnum.one.getValue());
		tranferModel.setPlanId(UUID.randomUUID().toString());
		tranferModel.setReferPlanId(model.getPlanCode());
		tranferModel.setGodNum("0");
		tranferModel.setCreateId(sysUser.getUserid());
		tranferModel.setCreateName(sysUser.getUsername());
		tranferModel.setCreateTime(DateUtils.getCurrentTime());
		tranferModel.setPlanPreCode("");
//		tranferModel.setPlanServiceAccount("");
//		tranferModel.setPlanServiceName("");
//		tranferModel.setPlanServiceStatus("");
//		tranferModel.setPlanServiceRemark("");
		tranferModel.setPlanServiceTime(DateUtils.getCurrentTime());
//		tranferModel.setPlanTmAccount("");
//		tranferModel.setPlanTmName("");
//		tranferModel.setPlanTmStatus("");
//		tranferModel.setPlanTmRemark("");
		tranferModel.setPlanTmTime(DateUtils.getCurrentTime());
//		tranferModel.setPlanStorAccount("");
//		tranferModel.setPlanStorName("");
//		tranferModel.setPlanStorStatus("");
//		tranferModel.setPlanStorRemark("");
		tranferModel.setPlanStorTime(DateUtils.getCurrentTime());
//		tranferModel.setPlanProdAccount("");
//		tranferModel.setPlanProdName("");
//		tranferModel.setPlanProdStatus("");
//		tranferModel.setPlanProdRemark("");
		tranferModel.setPlanProdTime(DateUtils.getCurrentTime());
//		tranferModel.setPlanExcAccount("");
//		tranferModel.setPlanExcName("");
//		tranferModel.setPlanExcStatus("");
		tranferModel.setPlanExcTime(DateUtils.getCurrentTime());
//		tranferModel.setPlanExcRemark("");
		tranferModel.setTransportCode("0");
		tranferModel.setTmCarrierName("");
		tranferModel.setTmCar("");
		tranferModel.setTmDriver("");
		tranferModel.setTmTank("");
		tranferModel.setTmUrl("");
		tranferModel.setEmsBillNum("0");
		tranferModel.setEmsGross(null);
		tranferModel.setEmsInTime("");
		tranferModel.setEmsOutTime("");
		tranferModel.setEmsTare(null);
		tranferModel.setEmsNnum(null);

		result += planDao.insert(tranferModel);
		List<PlanModel> successList = new ArrayList<PlanModel>();
		successList.add(tranferModel);
		HttpResult rfcHttpResult = callSapRfcService.createPlan(successList);
		if (rfcHttpResult.getCode() != HttpStatus.SUCCESS_CODE) {
			// 强制手动事务回滚
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return rfcHttpResult;
		}

		insertMsg(model, SysRoleEnum.planService.getName(), "转卸一条排货计划:");
		insertMsg(model, SysRoleEnum.planTm.getName(), "转卸一条排货计划:");
		insertMsg(model, SysRoleEnum.planStore.getName(), "转卸一条排货计划:");
		insertMsg(model, SysRoleEnum.planProd.getName(), "转卸一条排货计划:");

		if (result > 0) {
			httpResult.setMsg("转卸成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	@Transactional
	public HttpResult transfer(String planId, String planExcRemark) {
		if (!StringUtils.isNotNull(planId)) {
			return HttpResult.error("参数不能为空");
		}
		PlanModel model = planDao.load(planId);
		if (!model.getStatus().equals(TmPlanStatusEnum.one.getValue())
				&& !model.getStatus().equals(TmPlanStatusEnum.six.getValue())) {
			return HttpResult.error("只可取消已生效、已完成排货计划");
		}
		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (StringUtils.isNotNull(model.getPlanId())) {
			if (!sysUser.getSuperadmin().equals(Global.YES + "") && !model.getCreateId().equals(sysUser.getUserid())) {
				return HttpResult.error("非本人创建计划，不能转卸");
			}
		}
		HttpResult httpResult = new HttpResult();

		model.setStatus(TmPlanStatusEnum.four.getValue());
		model.setPlanExcAccount(sysUser.getLoginname());
		model.setPlanExcName(sysUser.getUsername());
		model.setPlanExcStatus(TmPlanStatusEnum.three.getValue());
		model.setPlanExcTime(DateUtils.getCurrentTime());
		model.setPlanExcRemark(planExcRemark);
		model.setPlanPreNum(BigDecimal.ZERO);
		int result = planDao.update(model);

		insertMsg(model, SysRoleEnum.planService.getName(), "转卸一条排货计划:");
		insertMsg(model, SysRoleEnum.planTm.getName(), "转卸一条排货计划:");
		insertMsg(model, SysRoleEnum.planStore.getName(), "转卸一条排货计划:");
		insertMsg(model, SysRoleEnum.planProd.getName(), "转卸一条排货计划:");

		if (result > 0) {
			httpResult.setMsg("转卸成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	@Transactional
	public HttpResult copy(String planId) {
		if (!StringUtils.isNotNull(planId)) {
			return HttpResult.error("参数不能为空");
		}
		PlanModel model = planDao.load(planId);

		HttpResult httpResult = new HttpResult();

		int result = planDao.update(model);

		PlanModel tranferModel = new PlanModel();
		BeanUtils.copyProperties(model, tranferModel);
		tranferModel.setPlanCode(commonService.createCode("tm_plan", "plan_code"));
		tranferModel.setPlanName(model.getPlanName() + "-复制");
		tranferModel.setStatus(TmPlanStatusEnum.zero.getValue());
		tranferModel.setPlanId(UUID.randomUUID().toString());
		tranferModel.setReferPlanId(model.getPlanCode());
		tranferModel.setPlanPreCode("");
		tranferModel.setGodNum("0");
		tranferModel.setCreateId("");
		tranferModel.setCreateName("");
		tranferModel.setCreateTime("");
		tranferModel.setPlanServiceAccount("");
		tranferModel.setPlanServiceName("");
		tranferModel.setPlanServiceStatus("");
		tranferModel.setPlanServiceRemark("");
		tranferModel.setPlanServiceTime("");
		tranferModel.setPlanTmAccount("");
		tranferModel.setPlanTmName("");
		tranferModel.setPlanTmStatus("");
		tranferModel.setPlanTmRemark("");
		tranferModel.setPlanTmTime("");
		tranferModel.setPlanStorAccount("");
		tranferModel.setPlanStorName("");
		tranferModel.setPlanStorStatus("");
		tranferModel.setPlanStorRemark("");
		tranferModel.setPlanStorTime("");
		tranferModel.setPlanProdAccount("");
		tranferModel.setPlanProdName("");
		tranferModel.setPlanProdStatus("");
		tranferModel.setPlanProdRemark("");
		tranferModel.setPlanProdTime("");
		tranferModel.setPlanExcAccount("");
		tranferModel.setPlanExcName("");
		tranferModel.setPlanExcStatus("");
		tranferModel.setPlanExcTime("");
		tranferModel.setPlanExcRemark("");
		tranferModel.setTransportCode("0");
		tranferModel.setTmCarrierName("");
		tranferModel.setTmCar("");
		tranferModel.setTmDriver("");
		tranferModel.setTmTank("");
		tranferModel.setTmUrl("");
		tranferModel.setEmsBillNum("0");
		tranferModel.setEmsGross(null);
		tranferModel.setEmsInTime("");
		tranferModel.setEmsOutTime("");
		tranferModel.setEmsTare(null);
		tranferModel.setEmsNnum(null);

		result += planDao.insert(tranferModel);

		if (result > 0) {
			httpResult.setMsg("复制成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	/**
	 * 导出
	 * 
	 * @param queryMap
	 * @param response
	 */
	public void export(Map<String, Object> queryMap, HttpServletResponse response) {
		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (!sysUser.getSuperadmin().equals(Global.YES + "")) {
			if (StringUtils.isNotNull(sysUser.getBtnPermission())) {
				if (sysUser.getBtnPermission().contains(FactoryEnum.xy.getValue())
						|| sysUser.getBtnPermission().contains(FactoryEnum.sp.getValue())
						|| sysUser.getBtnPermission().contains(FactoryEnum.hb.getValue())
						|| sysUser.getBtnPermission().contains(FactoryEnum.hk.getValue())) {
					queryMap.put("facCodes", sysUser.getBtnPermission().split(","));
				}
			} else {
			}
		}
		List<PlanModel> list = planDao.selectList(queryMap);
		for (PlanModel planModel : list) {
			BigDecimal bigDecimal1000 = new BigDecimal(1000);
			if (planModel.getPak1Num() != null && planModel.getPak1Num().compareTo(new BigDecimal(0)) > 0) {
				planModel.setUnitWeight(planModel.getProNum().multiply(bigDecimal1000).divide(planModel.getPak1Num())
						.setScale(BigDecimal.ROUND_CEILING));
			}
			planModel.setStatus(TmPlanStatusEnum.getEnumName(planModel.getStatus()));
			planModel.setPlanIsWeight(planModel.getPlanIsWeight().equals(Global.YES + "") ? "是" : "否");
		}
		logger.info("export:{}", list);
		try {
			EasyExcel.write(response.getOutputStream(), PlanModel.class).sheet("模板").doWrite(list);
		} catch (IOException e) {
			logger.error("导出错误:{}", e.getMessage());
		}

	}
}
